#lang racket


(require "../matrix.rkt"
         "../point.rkt")


(require "differenciation.rkt")


(provide (struct-out parametric-surface)
         parametric-surface-transformation
         make-simple-parametric-surface
         
         surface-tangent-default
         surface-normal-default)


(define-struct parametric-surface
  (domain-u domain-v object tangent normal transformation))


(define (surface-tangent-default object-proc)
  (λ (u v)
    (differenciate-tangent object-proc u v)))

(define (surface-normal-default object-proc)
  (λ (u v)
    (let* ((ts (differenciate-tangent object-proc u v))
           (u (first ts))
           (v (second ts)))
      (pxp u v))))

(define (make-simple-parametric-surface object-proc domain-u domain-v)
  (make-parametric-surface
   domain-u
   domain-v
   object-proc
   (surface-tangent-default object-proc)
   (surface-normal-default object-proc)
   m.identity))